local dummy = function() end

local backdrop = {
	bgFile = "Interface\\AddOns\\eMedia\\blank",
	edgeFile = "Interface\\AddOns\\eMedia\\blank", 
	tile = false, tileSize = 0, edgeSize = 1, 
	insets = {top = 1, left = 1, bottom = 1, right = 1},
}

CHAT_FLAG_AFK = '<AFK>'
CHAT_FLAG_DND = '<DND>'
CHAT_FLAG_GM = '<GM>'

CHAT_GUILD_GET = '|Hchannel:Guild|hG|h %s:\32'
CHAT_RAID_GET = '|Hchannel:raid|hR|h %s:\32'
CHAT_PARTY_GET = '|Hchannel:Party|hP|h %s:\32'
CHAT_RAID_WARNING_GET = 'RW %s:\32'
CHAT_RAID_LEADER_GET = '|Hchannel:raid|hRL|h %s:\32'
CHAT_OFFICER_GET = '|Hchannel:O|hO|h %s:\32'
CHAT_BATTLEGROUND_GET = '|Hchannel:Battleground|hB|h %s:\32'
CHAT_BATTLEGROUND_LEADER_GET = '|Hchannel:Battleground|hBL|h %s:\32'
CHAT_WHISPER_GET = 'from %s:\32'
CHAT_WHISPER_INFORM_GET = 'to %s:\32'


-- 1: index, 2: channelname, 3: twatt
-- Examples are based on this: [1. Channel] Otravi: Hi
--local str = '[%2$.3s] %s' -- gives: [Cha] Otravi: Hi
--local str = '[%d. %2$.3s] %s' -- gives: [1. Cha] Otravi: Hi
local str = '%d|h %3$s' -- gives: 1 Otravi: Hi
local function channel(...)
	return str:format(...)
end

local _AddMessage = ChatFrame1.AddMessage
local AddMessage = function(self, text, ...)
	if(type(text) == 'string') then
		text = text:gsub('|Hplayer:([^:]+):(%d+)|h%[(.-)%]|h', '|Hplayer:%1:%2|h%3|h')
		text = text:gsub('%[(%d+)%. (.+)%].+(|Hplayer.+)', channel)
	end

	return _AddMessage(self, text, ...)
end

local scroll = function(self, dir)
	if(dir > 0) then
		if(IsShiftKeyDown()) then
			self:ScrollToTop()
		elseif(IsControlKeyDown())	then
			for i=1,3 do self:ScrollUp() end
		else
			self:ScrollUp()
		end
	elseif(dir < 0) then
		if(IsShiftKeyDown()) then
			self:ScrollToBottom()
		elseif(IsControlKeyDown())	then
			for i=1,3 do self:ScrollDown() end
		else
			self:ScrollDown()
		end
	end
end

local buttons = {'UpButton', 'DownButton', 'BottomButton'}
for i=1, NUM_CHAT_WINDOWS do
	local cf = _G['ChatFrame'..i]
	cf:EnableMouseWheel(true)
	cf:SetScript('OnUpdate', nil)
	
	cf:SetFading(false)
	cf:SetScript('OnMouseWheel', scroll)
	
	--cf:SetFont(STANDARD_TEXT_FONT, 12, 'OUTLINE')
	--cf:SetShadowColor(0,0,0)
	--cf:SetShadowOffset(.1, -.1)	

	for k, button in pairs(buttons) do
		local butt = _G['ChatFrame'..i..button]
		butt:Hide()
		butt.Show = dummy
	end
	
	if(i ~= 2) then
		cf.AddMessage = AddMessage
		cf:SetMaxLines(1000)
	end
end
buttons = nil

ChatFrameMenuButton:ClearAllPoints()
ChatFrameEditBoxLanguage:SetPoint('TOPLEFT', ChatFrame1, -300, 0)
ChatFrameMenuButton:Hide()
--[[ChatFrameMenuButton.Show = dummy
ChatFrameMenuButton:SetParent(UIParent)
ChatFrameMenuButton:SetAlpha(0)
ChatFrameMenuButton:ClearAllPoints()
ChatFrameMenuButton:SetPoint('TOPLEFT', ChatFrame1, 0, 0)
ChatFrameMenuButton:SetScript('OnLeave', function(self) self:SetAlpha(0) end)
ChatFrameMenuButton:SetScript('OnEnter', function(self) self:SetAlpha(.5) end)
]]

local eb = ChatFrameEditBox
eb:ClearAllPoints()
eb:SetPoint('BOTTOMLEFT', ChatFrame1, 'TOPLEFT', -5, 0)
eb:SetPoint('BOTTOMRIGHT', ChatFrame1, 'TOPRIGHT', 0, 0)
eb:SetAltArrowKeyMode(false)

do
	local a, b, c = select(6, eb:GetRegions())
	a:Hide()
	b:Hide()
	c:Hide()
end

ChatTypeInfo['SAY'].sticky = 1
ChatTypeInfo['YELL'].sticky = 0
ChatTypeInfo['EMOTE'].sticky = 0
ChatTypeInfo['PARTY'].sticky = 1
ChatTypeInfo['GUILD'].sticky = 1
ChatTypeInfo['OFFICER'].sticky = 1
ChatTypeInfo['RAID'].sticky = 1
ChatTypeInfo['RAID_WARNING'].sticky = 0
ChatTypeInfo['BATTLEGROUND'].sticky = 1
ChatTypeInfo['WHISPER'].sticky = 0
ChatTypeInfo['CHANNEL'].sticky = 1

local function cf_config_event_handler(self, event, ...)
	CHAT_SHOW_ICONS = '1'
	if event == 'UPDATE_CHAT_COLOR_NAME_BY_CLASS' then
		for k in pairs(ChatTypeInfo) do
			ChatTypeInfo[k].colorNameByClass = true
		end
	end
end
if ChatFrame_ConfigEventHandler then
	hooksecurefunc('ChatFrame_ConfigEventHandler', cf_config_event_handler)
end
cf_config_event_handler(nil, 'UPDATE_CHAT_COLOR_NAME_BY_CLASS')

--[[ Modified version of MouseIsOver from UIParent.lua
local function MouseIsOver(frame)
	local s = frame:GetParent():GetEffectiveScale()
	local x, y = GetCursorPosition()
	x = x / s
	y = y / s

	local left = frame:GetLeft()
	local right = frame:GetRight()
	local top = frame:GetTop()
	local bottom = frame:GetBottom()

	-- Hack to fix a symptom not the real issue
	if(not left) then
		return
	end

	if((x > left and x < right) and (y > bottom and y < top)) then
		return 1
	else
		return
	end
end

local borderManipulation = function(...)
	for l = 1, select('#', ...) do
		local obj = select(l, ...)
		if(obj:GetObjectType() == 'FontString' and MouseIsOver(obj)) then
			return obj:GetText()
		end
	end
end

local _SetItemRef = SetItemRef
SetItemRef = function(link, text, button, ...)
	if(link:sub(1, 5) ~= 'yChat') then return _SetItemRef(link, text, button, ...) end

	local text = borderManipulation(SELECTED_CHAT_FRAME:GetRegions())
	if(text) then
		text = text:gsub('|c%x%x%x%x%x%x%x%x(.-)|r', '%1')
		text = text:gsub('|H.-|h(.-)|h', '%1')

		eb:Insert(text)
		eb:Show()
		eb:HighlightText()
		eb:SetFocus()
	end
end
]]
local editbox = CreateFrame('Button', nil, ChatFrameEditBox)
editbox:SetBackdrop(backdrop)
editbox:SetPoint('TOPLEFT', 'ChatFrameEditBoxLeft', 'TOPLEFT', 1, -4)
editbox:SetPoint('BOTTOMRIGHT', 'ChatFrameEditBoxRight', 'BOTTOMRIGHT', -1, 4)
editbox:SetFrameLevel(ChatFrameEditBox:GetFrameLevel()-1)

local function colorize(r,g,b)
	if type(r) == 'table' then
		if r.r then
			r,g,b = r.r, r.g, r.b
		else
			r,g,b = unpack(r)
		end
	end
	if r and g and b then
		editbox:SetBackdropBorderColor(r,g,b)
		editbox:SetBackdropColor(r/5,g/5,b/5, 0.7)
	end
end

hooksecurefunc('ChatEdit_UpdateHeader', function()
	local type = DEFAULT_CHAT_FRAME.editBox:GetAttribute('chatType')
	if ( type == 'CHANNEL' ) then
		local id = GetChannelName(DEFAULT_CHAT_FRAME.editBox:GetAttribute('channelTarget'))
		if id == 0 then	colorize(0.5,0.5,0.5)
		else colorize(ChatTypeInfo[type..id])
		end
	else colorize(ChatTypeInfo[type])
	end
end)

local function GetValidChannel(num)
	if num == 10 then return end
	for i = num + 1, 10 do
		if select(2, GetChannelName(i)) then
			return i
		end
	end
end

function ChatEdit_OnTabPressed(self)
	local chatType = self:GetAttribute('chatType')
	local channelTarget = self:GetAttribute('channelTarget')
	local inBG = UnitInBattleground('player') and true
	local inRaid = GetRealNumRaidMembers() > 0 and true
	local inParty = GetRealNumPartyMembers() > 0 and true
	local inGuild = IsInGuild() and true
	local setType
	
	if chatType == 'CHANNEL' then
		local channelNum = GetValidChannel(channelTarget)
		if channelNum then
			setType = chatType
			self:SetAttribute('channelTarget', channelNum)
		else
			setType = 'SAY'
		end
	elseif chatType == 'SAY' then
		setType = inBG and 'BATTLEGROUND' or inRaid and 'RAID' or inParty and 'PARTY' or inGuild and 'GUILD' or 'SAY'
	elseif chatType == 'BATTLEGROUND' then
		setType = inRaid and 'RAID' or inParty and 'PARTY' or inGuild and 'GUILD' or 'SAY'
	elseif chatType == 'RAID' then
		setType = inParty and 'PARTY' or inGuild and 'GUILD' or 'SAY'
	elseif chatType == 'PARTY' then
		setType = inGuild and 'GUILD' or 'SAY'
	elseif chatType == 'GUILD' then
		setType = 'OFFICER'
	elseif chatType == 'OFFICER' then
		setType = 'CHANNEL'
		self:SetAttribute('chatType', 'CHANNEL')
		self:SetAttribute('channelTarget', 1)
	end
	
	if setType then
		self:SetAttribute('chatType', setType)
		ChatEdit_UpdateHeader(self)
	else
		ChatEdit_SecureTabPressed(self)
	end
end

local ChannelSounds = {
	[5] = 'Sound\\Interface\\VoiceChatOn.wav',
	[8] = 'Sound\\Interface\\VoiceChatOn.wav',
}

local ChatSound, pName = CreateFrame'Frame', UnitName'player'
local ChatSoundEvents = {
	--['CHAT_MSG_GUILD'] = 'Sound\\Interface\\VoiceChatOn.wav',
	--['CHAT_MSG_OFFICER'] = 'Sound\\Interface\\VoiceChatOn.wav',
	['CHAT_MSG_WHISPER'] = 'Sound\\Interface\\iTellMessage.wav',
	['CHAT_MSG_PARTY'] = 'Sound\\Interface\\PlaceHolder.wav',
	['CHAT_MSG_RAID'] = 'Sound\\Interface\\PlaceHolder.wav',
	['CHAT_MSG_RAID_LEADER'] = 'Sound\\Interface\\PlaceHolder.wav',
	['CHAT_MSG_BATTLEGROUND'] = 'Sound\\Interface\\PlaceHolder.wav',
	['CHAT_MSG_BATTLEGROUND_LEADER'] = 'Sound\\Interface\\PlaceHolder.wav',
}

for k, v in pairs(ChatSoundEvents) do
	if k and v then
		ChatSound:RegisterEvent(k)
	end
end

ChatSound:SetScript('OnEvent', function(self, event, msg, sender, ...)
	if (not event) or (not msg) or (sender == pName) then return end
	
	-- check if the msg is filted
	local filter = ChatFrame_GetMessageEventFilters(event)
	if filter then
		for _, func in pairs(filter) do
			local filted, newmsg = func(self, event, msg, sender, ...)
			if filted and (not newmsg) then return end
		end
	end
	
	local sound = ChatSoundEvents[event]
	if sound and type(sound) == 'function' then
		sound = sound(msg, sender, ...)
	end
	if sound and type(sound) == 'string' then
		PlaySoundFile(sound)
	end
end)

local lines = {}
local frame = nil
local editBox = nil
local isf = nil

-----------------------------------------------------------------------------
-- Copy Chat
-----------------------------------------------------------------------------
local function CreatCopyFrame()
	frame = CreateFrame("Frame", "CopyFrame", UIParent)
	frame:SetBackdrop(backdrop)
	frame:SetBackdropColor(0, 0, 0, 0.8)
	frame:SetBackdropBorderColor(1, 1, 1, 0)
	frame:SetWidth(500)
	frame:SetHeight(300)
	frame:SetScale(0.85)
	frame:SetPoint("CENTER", UIParent, "CENTER")
	frame:Hide()
	frame:SetFrameStrata("DIALOG")

	local scrollArea = CreateFrame("ScrollFrame", "CopyScroll", frame, "UIPanelScrollFrameTemplate")
	scrollArea:SetPoint("TOPLEFT", frame, "TOPLEFT", 8, -30)
	scrollArea:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -30, 8)

	editBox = CreateFrame("EditBox", "CopyBox", frame)
	editBox:SetMultiLine(true)
	editBox:SetMaxLetters(99999)
	editBox:EnableMouse(true)
	editBox:SetAutoFocus(false)
	editBox:SetFontObject(ChatFontNormal)
	editBox:SetWidth(500)
	editBox:SetHeight(300)
	editBox:SetScript("OnEscapePressed", function() frame:Hide() end)

	scrollArea:SetScrollChild(editBox)

	local close = CreateFrame("Button", "CopyCloseButton", frame, "UIPanelCloseButton")
	close:SetPoint("TOPRIGHT", frame, "TOPRIGHT")

	isf = true
end

local function GetLines(...)
	--[[		Grab all those lines		]]--
	local ct = 1
	for i = select("#", ...), 1, -1 do
		local region = select(i, ...)
		if region:GetObjectType() == "FontString" then
			lines[ct] = tostring(region:GetText())
			ct = ct + 1
		end
	end
	return ct - 1
end

local function Copy(cf)
	local _, size = cf:GetFont()
	FCF_SetChatWindowFontSize(cf, cf, 0.01)
	local lineCt = GetLines(cf:GetRegions())
	local text = table.concat(lines, "\n", 1, lineCt)
	FCF_SetChatWindowFontSize(cf, cf, size)
	if not isf then CreatCopyFrame() end
	frame:Show()
	editBox:SetText(text)
	editBox:HighlightText(0)
end

for i = 1, NUM_CHAT_WINDOWS do
	local cf = _G[format("ChatFrame%d",  i)]
	local button = CreateFrame("Button", format("ButtonCF%d", i), cf)
	button:SetPoint("BOTTOMLEFT", -26, -27)
	button:SetHeight(32)
	button:SetWidth(32)
	button:SetAlpha(0)
	button:SetNormalTexture("Interface\\Chatframe\\UI-ChatIcon-ScrollUp-Up")
	button:SetScript("OnClick", function() Copy(cf) end)
	button:SetScript("OnEnter", function() 
		button:SetAlpha(1) 
		end)
	button:SetScript("OnLeave", function() button:SetAlpha(0) end)
	button:Hide()
	local tab = _G[format("ChatFrame%dTab", i)]
	tab:SetScript("OnShow", function() button:Show() end)
	tab:SetScript("OnHide", function() button:Hide() end)
end